<?php

namespace Modules\Auth\Services;

use App\Exceptions\BaseException;
use App\Exceptions\BusinessException;
use App\Exceptions\ServerException;
use App\Helpers\CodeResponse;
use App\Services\BaseService;
use Closure;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Http\Request;
use App\Http\Kernel;
use Illuminate\Support\Facades\Http;

class TokenService extends BaseService
{
    private $passportTokenUrl = '';

    public function __construct()
    {
        $this->passportTokenUrl = config('app.url') . "/" . config("auth.passport.prefix", 'oauth') . '/token';
        //        $this->passportPrefix = config("auth.passport.prefix", 'oauth');
    }

    /**
     * 销毁指定用户的当前token与 刷新token
     *
     * @param $user
     */
    public function logout($user)
    {
        $accessToken = $user->token();
        $this->RevokeRefreshTokensByAccessTokenId($accessToken);
    }

    /**
     * 销毁token 与 刷新token
     *
     * @param $token
     */
    public function RevokeRefreshTokensByAccessTokenId($token)
    {
        $refreshTokenRepository = app('Laravel\Passport\RefreshTokenRepository');
        $refreshTokenRepository->revokeRefreshTokensByAccessTokenId($token->id);
        $token->revoke();
    }

    /**
     * 通用登录
     *
     * @param       $username
     * @param       $password
     * @param array $options
     *
     * @return array
     * @throws GuzzleException
     * @author LL
     */
    public function Login($username, $password, array $options, Closure $callback): array
    {
        if ($callback) {
            /** @var \Closure $callback */
            $callback();
        }
        // $client = \DB::table('oauth_clients')->get();
        // dump($client->toArray(),$options);
        // dd($username,$password,$options);
        return $this->oauthPost(array_merge(
            [
                'grant_type' => 'password',
                'username' => $username,
                'password' => $password,
                'scope' => '*',
            ],
            $options
        ));
    }

    /**
     * 通用刷新token
     *
     * @param        $refresh_token
     * @param        $client_id
     * @param        $client_secret
     * @param string $scope
     *
     * @return mixed
     * @throws BaseException
     * @throws GuzzleException
     * @author LL
     */
    public function RefreshToken($refresh_token, $options)
    {
        return $this->oauthPost(array_merge(
            [
                'grant_type' => 'refresh_token',
                'refresh_token' => $refresh_token,
                'scope' => "*",
            ],
            $options
        ));
    }

    /**
     * 销毁指定用户的所有token 与刷新token
     *
     * @param $user
     */
    public function tokenAllRevoked($user)
    {
        $user->tokens->where('revoked', false)->each(function ($token, $key) {
            $this->RevokeRefreshTokensByAccessTokenId($token);
        });
    }

    private function oauthPost(array $param): array
    {
        $request = Request::create(route('passport.token'), 'POST', $param);
        $data = app(Kernel::class)->handle($request);
        if ($data->status() == 200) {
            return json_decode($data->content(), true);
        }
        $data->throwResponse();

        // try {
        //     $response = Http::asJson()->withoutVerifying()->post($this->passportTokenUrl, $param);
        //     $data = $response->getBody()->getContents();
        //     $data = json_decode($data, true);
        //     if ($response->ok()) {
        //         return $data;
        //     }
        //     throw new BusinessException(CodeResponse::CONFIG_FAIL, collect($data)->get('message'));
        // } catch (ClientException $exception) {
        //     throw new ServerException(CodeResponse::SERVER, $exception->getMessage());
        // }
        // return $data;
    }
}
